package com.usian.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usian.model.article.pojos.ApAuthor;
import com.usian.model.behavior.dtos.FollowBehaviorDto;
import com.usian.model.common.constants.FollowBehaviorConstants;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.user.dtos.UserRelationDto;
import com.usian.model.user.pojos.ApUser;
import com.usian.model.user.pojos.ApUserFan;
import com.usian.model.user.pojos.ApUserFollow;
import com.usian.user.feign.ArticleFeign;
import com.usian.user.mapper.ApUserFanMapper;
import com.usian.user.mapper.ApUserFollowMapper;
import com.usian.user.mapper.ApUserMapper;
import com.usian.user.service.ApUserFollowService;
import com.usian.utils.threadlocal.AppThreadLocalUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
public class ApUserFollowServiceImpl implements ApUserFollowService {

    @Autowired
    private ApUserFollowMapper apUserFollowMapper;

    @Autowired
    private ApUserFanMapper apUserFanMapper;

    @Autowired
    private ArticleFeign articleFeign;

    @Autowired
    private ApUserMapper apUserMapper;

    private static final short FOLLOW_OPERATION = 0;

    @Autowired
    private KafkaTemplate kafkaTemplate;


    @Override
    @Transactional
    public ResponseResult follow(UserRelationDto dto) {
        // 1.参数校验
        if (dto.getOperation() == null || dto.getOperation() < 0 || dto.getOperation() >1) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (dto.getAuthorId() == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        // 2.获取登录用户信息  userId
        ApUser currLoginUser = AppThreadLocalUtils.getUser();
        if (currLoginUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 3.通过feign查询作者信息
        ApAuthor apAuthor = articleFeign.findById(dto.getAuthorId());
        if (apAuthor == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "作者信息不存在！");
        }
        // 4.如果是关注
        if (dto.getOperation().shortValue() == FOLLOW_OPERATION) {
            // 4.1.插入ap_user_follow
            return followOperation(dto, apAuthor, currLoginUser);
            // 4.2.插入ap_user_fan
        } else {
            // 5.如果是取消关注
            return cancelFollowOperation(apAuthor, currLoginUser);

        }

    }

    private ResponseResult cancelFollowOperation(ApAuthor apAuthor, ApUser currLoginUser) {
        // 4.1.删除ap_user_follow
        LambdaQueryWrapper<ApUserFollow> userFollowLambdaQueryWrapper =
                Wrappers.<ApUserFollow>lambdaQuery().eq(ApUserFollow::getUserId, currLoginUser.getId()).eq(ApUserFollow::getFollowId, apAuthor.getUserId());

        int delFollowResult = apUserFollowMapper.delete(userFollowLambdaQueryWrapper);

        // 4.2.删除ap_user_fan
        LambdaQueryWrapper<ApUserFan> fanLambdaQueryWrapper =
                Wrappers.<ApUserFan>lambdaQuery().eq(ApUserFan::getUserId, apAuthor.getUserId()).eq(ApUserFan::getFansId, currLoginUser.getId());
        int delFanResult = apUserFanMapper.delete(fanLambdaQueryWrapper);
        if (delFollowResult == 0 || delFanResult == 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DELETE_FAIL, "取消关注失败");
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }


    private ResponseResult followOperation(UserRelationDto dto, ApAuthor apAuthor, ApUser currLoginUser) {

        // 4.1.插入 ap_user_follow
        List<ApUserFollow> followList =
                apUserFollowMapper.selectList(
                        Wrappers.<ApUserFollow>lambdaQuery()
                                .eq(ApUserFollow::getUserId, currLoginUser.getId())
                                .eq(ApUserFollow::getFollowId, apAuthor.getUserId()));

        if (followList != null && !followList.isEmpty()) {
            return ResponseResult.errorResult(500, "已经关注过了！");
        }
        LambdaQueryWrapper<ApUserFan> fanLambdaQueryWrapper =
                Wrappers.<ApUserFan>lambdaQuery().eq(ApUserFan::getUserId, apAuthor.getUserId()).eq(ApUserFan::getFansId, currLoginUser.getId());
        Integer fansCount = apUserFanMapper.selectCount(fanLambdaQueryWrapper);
        if (fansCount > 0) {
            return ResponseResult.errorResult(500, "已经关注过了！");
        }
        ApUser authorApUser = apUserMapper.selectById(apAuthor.getUserId());
        ApUserFollow apUserFollow = new ApUserFollow();
        apUserFollow.setUserId(currLoginUser.getId());
        apUserFollow.setFollowId(apAuthor.getUserId());
        apUserFollow.setFollowName(authorApUser.getName());
        apUserFollow.setLevel((short)0);
        apUserFollow.setIsNotice(true);
        apUserFollow.setCreatedTime(new Date());
        apUserFollowMapper.insert(apUserFollow);
        // 4.2.插入ap_user_fan
        ApUser loginApUser = apUserMapper.selectById(apAuthor.getUserId());
        ApUserFan apUserFan = new ApUserFan();
        apUserFan.setUserId(apAuthor.getUserId());
        apUserFan.setFansId(currLoginUser.getId().longValue());
        apUserFan.setFansName(loginApUser.getName());
        apUserFan.setLevel((short)0);
        apUserFan.setCreatedTime(new Date());
        apUserFan.setIsDisplay(true);
        apUserFan.setIsShieldLetter(false);
        apUserFan.setIsShieldComment(false);
        apUserFanMapper.insert(apUserFan);
        // 发送kafka消息
        FollowBehaviorDto followBehaviorDto = new FollowBehaviorDto();
        followBehaviorDto.setArticleId(dto.getArticleId());
        followBehaviorDto.setFollowId(apAuthor.getUserId());
        followBehaviorDto.setUserId(currLoginUser.getId());
        kafkaTemplate.send(FollowBehaviorConstants.FOLLOW_BEHAVIOR_TOPIC, JSON.toJSONString(followBehaviorDto));
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);

    }
}
